package com.qydp.rpc.server;

import com.qydp.rpc.model.RequestModel;
import com.qydp.rpc.model.ResponseModel;
import com.qydp.rpc.registry.ServiceRegistry;
import com.qydp.rpc.serializer.JdkSerializer;
import com.qydp.rpc.serializer.Serializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author shuSheng
 * @description
 * @since 2024-07-23 15:32
 */

public class HttpServerHandler implements Handler<HttpServerRequest> {
    final Serializer serializer = new JdkSerializer();


    @Override
    public void handle(HttpServerRequest req) {
        req.bodyHandler(body -> {


            System.out.println("log:HttpServerHandler handle" + body.toString());
            byte[] bytes = body.getBytes();


            RequestModel requestModel = null;
            try {
                requestModel = serializer.deserialize(bytes, RequestModel.class);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //构建返回值
            ResponseModel responseModel = new ResponseModel();
            String methodName = requestModel.getMethodName();
            String serviceName = requestModel.getServiceName();
            Object[] args = requestModel.getArgs();
            Class<?>[] parameterTypes = requestModel.getParameterTypes();

            Class<?> service = ServiceRegistry.getService(serviceName);
            Method method = null;
            try {
                method = service.getMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
            Object result = null;
            try {
                result = method.invoke(service.newInstance(), args);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            }

            responseModel.setResult(result);
            doResponse(req, responseModel);
        });


    }

    /**
     * 构建返回值
     *
     * @param req
     * @param responseModel
     */
    public void doResponse(HttpServerRequest req, ResponseModel responseModel) {
        HttpServerResponse response = req.response();
        response.putHeader("content-type", "application/json");

        try {
            byte[] serialize = serializer.serialize(responseModel);
            response.end(Buffer.buffer(serialize));

        } catch (IOException e) {
            response.end(Buffer.buffer());
            throw new RuntimeException(e);
        }

    }
}

